/*
 * @Author: intellectual-seeker 3336339701@qq.com
 * @Date: 2025-08-25 21:09:55
 * @LastEditors: intellectual-seeker 3336339701@qq.com
 * @LastEditTime: 2025-08-26 15:31:39
 * @FilePath: /code/lesson29/testSig.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
using namespace std;
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>

//SIGCHLD信号捕捉与非阻塞子进程回收
//version1
void handler(int signo)
{
    pid_t rid = waitpid(-1, nullptr, 0);//只回收了一个，回收任意一个
    if(rid > 0)
    {
        cout << "wait success..." << endl;
    }
}

//version2
// void handler(int signo)
// {
//     while(true)
//     {
//         pid_t rid = waitpid(-1, nullptr, 0);
//         if(rid > 0)
//         {
//             cout << "wait success... , child pid is : " << rid << endl;
//         }
//         else if(rid <= 0)
//         {
//             break;
//         }
//     }
//     cout << "wait sub process done" << endl;
// }

//version3
// void handler(int signo)
// {
//     while(true)
//     {
//         pid_t rid = waitpid(-1, nullptr, WNOHANG);
//         if(rid > 0)
//         {
//             cout << "wait success... , child pid is : " << rid << endl;
//         }
//         else if(rid <= 0)
//         {
//             break;
//         }
//     }
//      cout << "wait sub process done" << endl;
// }

// int main()
// {
//     signal(SIGCHLD, handler);

//     int cnt = 2;
//     while(cnt--)
//     {
//         pid_t id = fork();
//         if(id == 0 && cnt)
//         {
//             sleep(5);
//             exit(0);
//         }
//         else if(id == 0 && !cnt)
//         {
//             sleep(20);
//             exit(0);
//         }
//     }

//     while(true)
//     {
//         sleep(1);
//     }

//     return 0;
// }

int main()
{
    //signal(SIGCHLD, handler);
    signal(SIGCHLD, SIG_IGN);

    //创建多个子进程
    for(int i = 0; i < 5; i++)
    {
        pid_t id = fork();

        if(id == 0)
        {
            int cnt = 5;
            while(cnt--)
            {
                //cout << "child process : " << getpid() << endl;
                sleep(1);
            }
            cout << "child process died..." << endl;
            exit(0); 
        }
    }

    while(true)
    {
        sleep(1);
    }

    return 0;
}

// int main()
// {
//     signal(SIGCHLD, handler);

//     //创建多个子进程
//     for(int i = 0; i < 5; i++)
//     {
//         pid_t id = fork();

//         //子进程
//         if(id == 0)
//         {
//             cout << "child process : " << getpid() << endl;
//             sleep(5);
//             exit(0); 
//         }

//         sleep(2);
//     }

//     //父进程
//     //1. 不回收观察子进程是否僵尸
//     //2. handler内只回收一个子进程，waitpid后程序直接结束?
//     //3. handler循环阻塞waitpid回收子进程，收到信号后，进行循环阻塞回收时，还有子进程没退出
//     sleep(100);

//     return 0;
// }

// void PrintPending(sigset_t pending)
// {
//     cout << "pid is : " << getpid() << " pending is : ";
//     for(int i = 31; i > 0; i--)
//     {
//         if(sigismember(&pending, i))
//         {
//             cout << "1";
//         }
//         else
//         {
//             cout << "0";
//         }
//     }
//     cout << endl;
// }

// void handler(int signo)
// {
//     cout << "signo is : " << signo << endl;
//     sigset_t pending;
//     while(true)//普通信号的处理会被打断
//     {
//         sigpending(&pending);
//         PrintPending(pending);
//         sleep(1);
//     }
// }

// int main()
// {
//     //系统调用接口sigaction的使用
//     //自定义2号信号handler，屏蔽3、4、5号信号
//     struct sigaction act, o_act;

//     sigset_t sig;
//     sigemptyset(&sig);
//     //sigaddset(&sig, 3);
//     sigaddset(&sig, 4);
//     sigaddset(&sig, 5);

//     //设置sigaction参数
//     act.sa_handler = handler;//没有自动补全
//     act.sa_mask = sig;//仅限于信号处理期间会屏蔽
//     act.sa_flags = 0;

//     sigaction(SIGINT, &act, &o_act);

//     //sigset_t pending;
//     while(true)
//     {
//         //sigpending(&pending);
//         //PrintPending(pending);
//         sleep(1);
//     }

//     return 0;
// }